﻿using System;
using Utils;

namespace StockEngine.RealTime
{
	public class AcquisitionSystemInformation : PropertyChangedNotifier, IDisposable
	{
		#region Attributes

		private readonly AcquisitionScheduler _scheduler;
		private readonly AcquisitionEngine _engine;
	    private readonly Acquisitor _acquisitor;

		private AcquisitionSystemState _state;

		#endregion

		#region Properties

		public AcquisitionSystemState State
		{
			get
			{
				return _state;
			}
			set
			{
				if(_state != value)
				{
					_state = value;
					base.OnPropertyChangedAsync("State");
				}
			}
		}

		public bool CaptureStarted
		{
			get
			{
				return _engine.Started;
			}
		}

		public DateTime? LastSchedulerCheck
		{
			get
			{
				return _scheduler.LastCheck;
			}
		}

	    public int SkippedItems
	    {
	        get
	        {
                return _acquisitor.SkippedItems;
	        }
	    }

		#endregion

		#region Public Methods

		internal AcquisitionSystemInformation(AcquisitionScheduler scheduler,AcquisitionEngine engine, Acquisitor acquisitor)
		{
			this.State = AcquisitionSystemState.Disabled;

			_scheduler = scheduler;
			_engine = engine;
		    _acquisitor = acquisitor;

			_scheduler.PropertyChanged += this.Scheduler_PropertyChanged; // Disposed
			_engine.PropertyChanged += this.Engine_PropertyChanged; // Disposed
			_acquisitor.PropertyChanged += this.Acquisitor_PropertyChanged; // Disposed
		}

		#endregion

		#region Event Handlers

        private void Acquisitor_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
			base.OnPropertyChangedAsync(e.PropertyName);
		}

		private void Engine_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "Started")
			{
				base.OnPropertyChangedAsync("CaptureStarted");
			}
		}

		private void Scheduler_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
		{
			if (e.PropertyName == "LastCheck")
			{
				base.OnPropertyChangedAsync("LastSchedulerCheck");
			}
			else if (e.PropertyName == "Started")
			{
				if (_scheduler.Started)
				{
					this.State = AcquisitionSystemState.Enabled;	
				}
			}
			else if (e.PropertyName == "Stopped")
			{
				if (_scheduler.Stopped)
				{
					this.State = AcquisitionSystemState.Disabled;
				}
			}
		}

		#endregion

		#region IDisposable

		protected bool Disposed { get; private set; }

		private void Dispose(bool disposing)
		{
			if (!this.Disposed)
			{
				this.InternalDispose(disposing);
			}

			this.Disposed = true;
		}

		protected virtual void InternalDispose(bool disposing)
		{
			if (disposing)
			{
				_scheduler.PropertyChanged -= this.Scheduler_PropertyChanged; 
				_engine.PropertyChanged -= this.Engine_PropertyChanged; 
				_acquisitor.PropertyChanged -= this.Acquisitor_PropertyChanged; 
			}

			// Dispose here only unmanaged objects 
			// Don’t use managed objects here because maybe 
			// they have been finalized already
		}

		public void Dispose()
		{
			this.Dispose(true);
			GC.SuppressFinalize(this);
		}

		~AcquisitionSystemInformation()
		{
			this.Dispose(false);
		}

		#endregion
	}
}